package com.mnb.beidou.server;


import com.mnb.beidou.config.TcpServerProperties;
import com.mnb.beidou.handler.TcpServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * TCP服务器
 */
@Component
public class TcpServer {

    private static final Logger logger = LoggerFactory.getLogger(TcpServer.class);

    @Autowired
    private TcpServerProperties properties;

    @Autowired
    private TcpServerInitializer channelInitializer;

    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private ChannelFuture serverChannelFuture;

    @PostConstruct
    public void start() throws Exception {
        logger.info("启动TCP服务器，端口: {}", properties.getPort());

        // 创建事件循环组
        bossGroup = new NioEventLoopGroup(properties.getBossThreads());
        workerGroup = new NioEventLoopGroup(properties.getWorkerThreads());

        try {
            // 创建服务器启动引导
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(channelInitializer)
                    .option(ChannelOption.SO_BACKLOG, properties.getBacklog())
                    .option(ChannelOption.SO_REUSEADDR, properties.isReuseAddress())
                    .childOption(ChannelOption.SO_KEEPALIVE, properties.isKeepAlive())
                    .childOption(ChannelOption.TCP_NODELAY, true)
                    .childOption(ChannelOption.SO_RCVBUF, 1024 * 1024)
                    .childOption(ChannelOption.SO_SNDBUF, 1024 * 1024);

            // 绑定端口并启动服务器
            serverChannelFuture = bootstrap.bind(properties.getPort()).sync();

            logger.info("TCP服务器启动成功，监听端口: {}", properties.getPort());

            // 异步等待服务器关闭，避免阻塞主线程
            serverChannelFuture.channel().closeFuture().addListener(future -> {
                logger.info("TCP服务器已关闭");
            });

        } catch (Exception e) {
            logger.error("启动TCP服务器失败", e);
            throw e;
        }
    }

    @PreDestroy
    public void shutdown() {
        logger.info("正在关闭TCP服务器...");

        if (serverChannelFuture != null) {
            serverChannelFuture.channel().close();
        }

        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }

        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }

        logger.info("TCP服务器已关闭");
    }

    /**
     * 获取服务器状态
     * @return 服务器状态信息
     */
    public String getServerStatus() {
        if (serverChannelFuture != null && serverChannelFuture.channel().isActive()) {
            return "运行中";
        } else {
            return "已停止";
        }
    }

    /**
     * 获取服务器端口
     * @return 服务器端口
     */
    public int getServerPort() {
        return properties.getPort();
    }
}
